package wasnake.actors;

import java.awt.Color;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import wasnake.grid.Direction;
import wasnake.grid.Grid;
import wasnake.grid.Location;

/**
 * A moving actor that blocks other actors.
 * @author Mark
 */
public class Moose extends Actor {
    /** The cell that composes this moose.*/
    private Cell cell;
    
    /**
     * Creates a new moose.
     * @param color The color of the moose.
     */
    public Moose(Color color, Direction direction) {
        super(color, direction);
    }

    @Override
    public void putSelfInGrid(Grid<Cell> grid, Location location) {
    	synchronized(grid) {
	        if(this.grid != null)
	            throw new IllegalStateException(
	                    "This moose is already contained in a grid.");
	        if(!grid.isValid(location))
	            throw new IllegalStateException(
	                    "The location given is not valid.");
	        this.grid = grid;
	        if(grid.get(location) != null)
	            grid.get(location).getOwner().removeSelfFromGrid();
	        cell = new Cell(this, location);
	        grid.put(location, cell);
    	}
    }

    @Override
    public void removeSelfFromGrid() {
    	synchronized(grid) {
	        if(cell == null)
	            throw new IllegalStateException(
	                    "This moose is not contained in a grid.");
	        grid.remove(cell.getLocation());
	        cell = null;
	        grid = null;
    	}
    }

    @Override
    public Set<Cell> getCells() {
        Set<Cell> cells = new HashSet<Cell>();
        cells.add(cell);
        return cells;
    }

    @Override
    public void act() {
    	synchronized(grid) {
	        // Only move 50% of the time
	        Random random = new Random();
	        if(random.nextDouble() > 0.5)
	            return;
	        // Choose a random direction to move in
	        direction = Direction.cardinals()[random.nextInt(4)];
	        // Find the location to move the moose to
	        Location moveTo = cell.getLocation().getAdjacentLocation(direction);
	        // If the moose runs out of bounds, it dies
	        if(!grid.isValid(moveTo)) {
	            removeSelfFromGrid();
	            return;
	        }
	        // Retrieve the cell in the location to move to
	        Cell nextCell = grid.get(moveTo);
	        // If the cell to move to contains an actor, check which actor
	        if(nextCell != null) {
	            // If the actor is a food, eat it
	            if(nextCell.getOwner().getClass() == Food.class)
	                nextCell.getOwner().removeSelfFromGrid();
	            // Otherwise, the moose dies
	            else
	                removeSelfFromGrid();
	        // Otherwise if the cell is empty, move the moose
	        } else {
	            // Remove the moose from the grid
	            grid.remove(cell.getLocation());
	            // Reset the moose's cell to a new location
	            cell = new Cell(this, moveTo);
	            // Add the moose back to the grid
	            grid.put(moveTo, cell);
	        }
    	}
    }
    
}
